﻿using System.Collections.Generic;
using SlimMath;

namespace JamesZhao.Engine.Graphics.Geometry
{
    public class MeshData
    {
        public MeshData()
        {
            Vertices = new List<Vertex>();
            Triangles = new List<Triangle>();
        }

        public IList<Vertex> Vertices { get; private set; }
        public IList<Triangle> Triangles { get; private set; }
        public static MeshData LoadPlaneMesh(int yCount, int xCount)
        {
            var md = new MeshData();
            var y = 0;

            //extra verts on the sides
            yCount++;
            xCount++;

            for (var i = 0; i < yCount; i++)
            {
                for (var j = 0; j < xCount ; j++)
                {
                    md.Vertices.Add(new Vertex
                                        {
                                            Position = new Vector4(i, y, j, 0),
                                            Color = new Vector4(1,1,1,1),
                                            Normal = new Vector3(0, 1, 0)
                                        });
                    //if it's not the last row
                    if (i < yCount - 1 && j < xCount - 1)
                    {
                        md.Triangles.Add(new Triangle
                                             {
                                                 Verts = new int[]
                                                             {
                                                                 //i*xCount + j,  i*xCount + j + 1
                                                                 //| --------
                                                                 //|       /
                                                                 //|    / 
                                                                 //| /  
                                                                 //(i + 1)*xCount + j
                                                                 (i + 1)*xCount + j, 
                                                                 i*xCount + j, 
                                                                 i*xCount + j + 1,
                                                                 // (counter clockwise)
                                                             }
                                             });

                        md.Triangles.Add(new Triangle
                                             {
                                                 Verts = new int[]
                                                             {
                                                                 //        i*xCount + j + 1
                                                                 //         |
                                                                 //       / |
                                                                 //    /    |
                                                                 // /       |
                                                                 //| --------
                                                                 //(i + 1)*xCount + j       (i + 1)*xCount + j + 1
                                                                 (i + 1)*xCount + j,
                                                                 i*xCount + j + 1, 
                                                                 (i + 1)*xCount + j + 1 // (counter clockwise)
                                                             }
                                             });
                    }
                }

                //add a vert at the end
            }
            return md;
        }

        public static MeshData LoadFullScreenQuad()
        {
            var md = new MeshData();
            float z = .5f;
            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(-1, -1, z, 1.0f)
                                });

            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(-1, 1, z, 1.0f)
                                });
            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(1, 1, z, 1.0f)
                                });
            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(1, -1, z, 1.0f)
                                });

            md.Triangles.Add(new Triangle {Verts = new[] {0, 1, 2}});
            md.Triangles.Add(new Triangle {Verts = new[] {2, 3, 0}});

            return md;
        }

        public static MeshData LoadTestMeshData()
        {
            var md = new MeshData();
            const float z = 2;
            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(0.0f, 0.5f, z, 1.0f),
                                    Color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f)
                                });

            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(0.5f, -0.5f, z, 1.0f),
                                    Color = new Vector4(0.0f, 1.0f, 0.0f, 1.0f)
                                });
            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(-0.5f, -0.5f, z, 1.0f),
                                    Color = new Vector4(0.0f, 0.0f, 1.0f, 1.0f)
                                });


            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(1.0f, 0.5f, z, 1.0f),
                                    Color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f)
                                });

            md.Vertices.Add(new Vertex
                                {
                                    Position = new Vector4(-1.0f, 0.5f, z, 1.0f),
                                    Color = new Vector4(1.0f, 0.0f, 0.0f, 1.0f)
                                });

            md.Triangles.Add(new Triangle {Verts = new[] {0, 1, 2}});
            md.Triangles.Add(new Triangle {Verts = new[] {0, 3, 1}});
            md.Triangles.Add(new Triangle {Verts = new[] {4, 0, 2}});

            return md;
        }
    }
}